import tkinter as tk
import random
import yaml
import pyperclip

# 全局变量用于保存固定角色设置
fixed_roles = {}

# 读取并打乱身份
def load_roles_from_yaml():
    with open('sf.yaml', 'r', encoding='utf-8') as file:
        data = yaml.safe_load(file)
    
    neutral_roles = data.get('zhongli', [])
    good_roles = data.get('haoren', [])
    bad_roles = data.get('huairen', [])
    return neutral_roles, good_roles, bad_roles

# 根据输入的数量生成角色列表
def generate_roles():
    neutral_roles, good_roles, bad_roles = load_roles_from_yaml()
    
    num_neutral = neutral_entry.get().strip()
    num_good = good_entry.get().strip()
    num_bad = bad_entry.get().strip()
    
    if not num_neutral or not num_good or not num_bad:
        return None  # 如果有输入框为空，返回 None

    try:
        num_neutral = int(num_neutral)
        num_good = int(num_good)
        num_bad = int(num_bad)
    except ValueError:
        return None  # 如果输入的不是整数，返回 None

    # 排除固定角色
    fixed_role_indices = fixed_roles.keys()
    available_neutral_roles = [role for i, role in enumerate(neutral_roles) if i + 1 not in fixed_role_indices]
    available_good_roles = [role for i, role in enumerate(good_roles) if i + 1 not in fixed_role_indices]
    available_bad_roles = [role for i, role in enumerate(bad_roles) if i + 1 not in fixed_role_indices]

    selected_neutral = random.sample(available_neutral_roles, min(num_neutral - len([r for i, r in fixed_roles.items() if "中立阵营" in r]), len(available_neutral_roles)))
    selected_good = random.sample(available_good_roles, min(num_good - len([r for i, r in fixed_roles.items() if "好人阵营" in r]), len(available_good_roles)))
    selected_bad = random.sample(available_bad_roles, min(num_bad - len([r for i, r in fixed_roles.items() if "坏人阵营" in r]), len(available_bad_roles)))

    all_roles = selected_neutral + selected_good + selected_bad

    # 应用固定角色设置
    for idx, role in fixed_roles.items():
        if 1 <= idx <= len(all_roles):
            all_roles.insert(idx - 1, role)
    
    return all_roles

# 复制身份到剪贴板
def copy_to_clipboard(index, role):
    text = f"{index + 1}. {role}"
    pyperclip.copy(text)

# 处理坏人角色
def adjust_bad_roles(roles):
    imitation_id = find_imitation_id(roles)
    has_imitation = "当中有模仿者" if imitation_id else "当中没有模仿者"
    
    meat_juice_id = find_meat_juice_id(roles)
    if meat_juice_id:
        meat_juice_str = f"{meat_juice_id}号为肉汁"
    else:
        meat_juice_str = "本场没有肉汁"
    
    bad_role_indices = [i + 1 for i, role in enumerate(roles) if "坏人阵营" in role]
    if imitation_id:
        bad_role_indices.append(imitation_id)
    
    random.shuffle(bad_role_indices)
    bad_role_indices_str = '/'.join(map(str, bad_role_indices)) + "是你的队友"

    for i in range(len(roles)):
        if "坏人阵营" in roles[i]:
            roles[i] += f"，{bad_role_indices_str}，{has_imitation}，{meat_juice_str}"

# 查找模仿者的序号
def find_imitation_id(all_roles):
    for idx, role in enumerate(all_roles):
        if "模仿者" in role:
            return idx + 1
    return None

# 查找灰暗警长的序号
def find_gray_dusk_id(all_roles):
    for idx, role in enumerate(all_roles):
        if "灰暗警长" in role:
            return idx + 1
    return None

# 查找肉汁的序号
def find_meat_juice_id(all_roles):
    for idx, role in enumerate(all_roles):
        if "肉汁" in role:
            return idx + 1
    return None

# 抽取并打乱身份，并添加到界面
def draw_and_display_roles():
    for widget in result_frame.winfo_children():
        widget.destroy()

    # 先生成角色
    all_roles = generate_roles()
    if all_roles is None:
        role_label = tk.Label(result_frame, text="请检查输入的角色数量", justify='left', fg='red')
        role_label.grid(row=0, column=0, sticky='w')
        return

    random.shuffle(all_roles)

    gray_dusk_id = find_gray_dusk_id(all_roles)
    if gray_dusk_id is not None:
        for i in range(len(all_roles)):
            if "中立阵营" in all_roles[i]:
                all_roles[i] += f"，{gray_dusk_id}号是灰暗警长"
    else:
        for i in range(len(all_roles)):
            if "中立阵营" in all_roles[i]:
                all_roles[i] += "，本场没有灰暗警长"

    adjust_bad_roles(all_roles)
    save_to_file(all_roles)

    # 应用固定角色设置
    updated_roles = []
    used_indices = set()

    for i, role in enumerate(all_roles):
        if (i + 1) in fixed_roles:
            updated_roles.append(fixed_roles[i + 1])
            used_indices.add(i + 1)
        else:
            updated_roles.append(role)
    
    for i in range(1, len(all_roles) + 1):
        if i not in used_indices and (i <= len(updated_roles)):
            if (i not in fixed_roles):
                # Ensure randomization of the remaining roles
                available_roles = [role for role in all_roles if role not in updated_roles]
                if available_roles:
                    updated_roles[i - 1] = random.choice(available_roles)

    for i, role in enumerate(updated_roles):
        copy_button = tk.Button(result_frame, text="复制", command=lambda i=i, r=role: copy_to_clipboard(i, r))
        copy_button.grid(row=i, column=0, sticky='w', padx=5)
        role_label = tk.Label(result_frame, text=f"{i + 1}. {role}", justify='left')
        role_label.grid(row=i, column=1, sticky='w', padx=5)

def save_to_file(roles):
    with open('roles.txt', 'w', encoding='utf-8') as file:
        for i, role in enumerate(roles):
            file.write(f"{i + 1}. {role}\n")

# 打开设置窗口
def open_settings(event=None):
    settings_window = tk.Toplevel(window)
    settings_window.title("设置固定身份")
    settings_window.geometry("300x300")

    # 玩家序号输入框
    tk.Label(settings_window, text="玩家序号 (用空格分隔):").pack(pady=10)
    player_index_entry = tk.Entry(settings_window)
    player_index_entry.pack(pady=5)

    dropdowns = []

    # 确定按钮，生成下拉选项框
    def generate_dropdowns():
        indices = player_index_entry.get().strip().split()
        for idx in indices:
            frame = tk.Frame(settings_window)
            frame.pack(pady=5)
            tk.Label(frame, text=f"玩家 {idx}:").pack(side="left")

            role_var = tk.StringVar(settings_window)
            role_var.set("选择角色")
            neutral_roles, good_roles, bad_roles = load_roles_from_yaml()
            all_roles = neutral_roles + good_roles + bad_roles

            role_menu = tk.OptionMenu(frame, role_var, *all_roles)
            role_menu.pack(side="left")
            dropdowns.append((idx, role_var))

        # 提交按钮，应用固定角色设置
        def apply_fixed_roles():
            for idx, role_var in dropdowns:
                fixed_roles[int(idx)] = role_var.get()
            settings_window.destroy()
            draw_and_display_roles()  # 更新主界面

        submit_button = tk.Button(settings_window, text="提交", command=apply_fixed_roles)
        submit_button.pack(pady=10)

    generate_button = tk.Button(settings_window, text="确定", command=generate_dropdowns)
    generate_button.pack(pady=5)

# 创建主窗口
window = tk.Tk()
window.title("鹅鸭杀身份随机抽取")

# 设置窗口大小为屏幕的一半
screen_width = window.winfo_screenwidth()
screen_height = window.winfo_screenheight()
window_width = screen_width // 2
window_height = screen_height // 2
window.geometry(f"{window_width}x{window_height}")

# 使窗口布局可调整
window.grid_rowconfigure(0, weight=1)
window.grid_columnconfigure(0, weight=1)

# 创建一个 Canvas 用于包裹所有内容
main_canvas = tk.Canvas(window)
main_canvas.grid(row=0, column=0, sticky="nsew")

# 创建一个包含滚动条的 Frame
scrollbar = tk.Scrollbar(window, orient="vertical", command=main_canvas.yview)
scrollbar.grid(row=0, column=1, sticky="ns")

# 让 Canvas 与 Scrollbar 连接
main_canvas.configure(yscrollcommand=scrollbar.set)

# 创建一个 Frame 放在 Canvas 中，用于放置所有小组件
content_frame = tk.Frame(main_canvas)

# 将 Frame 放入 Canvas
main_canvas.create_window((0, 0), window=content_frame, anchor="nw")

# 中立角色输入框
neutral_label = tk.Label(content_frame, text="中立角色数量:")
neutral_label.grid(row=0, column=0, sticky='w', padx=5, pady=5)
neutral_entry = tk.Entry(content_frame)
neutral_entry.grid(row=0, column=1, sticky='w', padx=5, pady=5)

# 好人角色输入框
good_label = tk.Label(content_frame, text="好人角色数量:")
good_label.grid(row=1, column=0, sticky='w', padx=5, pady=5)
good_entry = tk.Entry(content_frame)
good_entry.grid(row=1, column=1, sticky='w', padx=5, pady=5)

# 坏人角色输入框
bad_label = tk.Label(content_frame, text="坏人角色数量:")
bad_label.grid(row=2, column=0, sticky='w', padx=5, pady=5)
bad_entry = tk.Entry(content_frame)
bad_entry.grid(row=2, column=1, sticky='w', padx=5, pady=5)

# 抽取按钮
draw_button = tk.Button(content_frame, text="抽取身份", command=draw_and_display_roles)
draw_button.grid(row=3, column=0, columnspan=2, pady=10)

# 显示结果的 Frame
result_frame = tk.Frame(content_frame)
result_frame.grid(row=4, column=0, columnspan=2, sticky='w', padx=5, pady=5)

# 绑定 Tab 键打开设置窗口
window.bind('<Tab>', open_settings)

# 使得窗口的大小变化时，内容自动适应
content_frame.bind("<Configure>", lambda e: main_canvas.configure(scrollregion=main_canvas.bbox("all")))

# 鼠标滚轮事件绑定（使滚轮控制滑动）
window.bind_all("<MouseWheel>", lambda event: main_canvas.yview_scroll(int(-1*(event.delta/120)), "units"))

# 运行主循环
window.mainloop()
